/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.lian.jvkontakte;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.CharBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;

/**
 *
 * @author limachkoaa
 */
public class Connection {
//    public static final String DEFAULT_SERVER_ADDRESS = "vkontakte.ru";
//    public static final String DEFAULT_PREFIX = "http://";
//    public static final String DEFAULT_POSTFIX = "/";
    public static final int LOGIN_BAD_ARGUMENT = -2;
    public static final int LOGIN_OK = 1;
    public static final int LOGIN_ALREADY_LOGGED = -1;
    public static final int LOGIN_ERROR = 0;
    public static final int LOGINSTATUS_LOGGED = 1;
    public static final int LOGINSTATUS_UNLOGGED = 0;
//    private static final String DEFAULT_EMAIL_STRING = "email";
//    private static final String DEFAULT_PASS_STRING = "pass";
//    private static final String DEFAULT_LOGIN_PAGE = "login.php";
//    private static final String DEFAULT_COOKIE_USERID_NAME = "remixmid";
//    private static final String DEFAULT_COOKIE_LANG_NAME = "remixlang";

    private DefaultHttpClient client;
    private String serverAddress;
    private String email;
    private String pass;
    private int loginStatus;
    private String userID;
    private Map<String, Object> ini;
    private Map<String, String> connConfig;

    /**
     * Создаёт новый объект подключения
     * @param serverAddress адрес сервера вида vkontakte.ru
     */
    public Connection(String serverAddress, Map<String, Object> ini) {
        this.serverAddress = serverAddress;
        this.client = new DefaultHttpClient();
        this.ini = ini;
        connConfig = (Map<String, String>) ini.get("connection");
    }

    /**
     * Создаёт новый объект подключения
     * По умолчанию адрес сервера vkontakte.ru
     */
    public Connection(Map<String, Object> ini) {
        this.ini = ini;
        connConfig = (Map<String, String>) ini.get("connection");
        this.serverAddress = connConfig.get("DEFAULT_SERVER_ADDRESS");
        this.client = new DefaultHttpClient();
    }

    /**
     *
     * @return Возвращает адрес сервера вида http://vkontakte.ru/
     */
    public String getServerAddress() {
        return connConfig.get("DEFAULT_PREFIX") + serverAddress + connConfig.get("DEFAULT_POSTFIX");
    }

    public int getLoginStatus() {
        return loginStatus;
    }

    private void setLoginStatus(int loginStatus) {
        this.loginStatus = loginStatus;
    }

    public String getUserID() {
        return userID;
    }

    private void setUserID(String userID) {
        this.userID = userID;
    }

    public void fixLang(int lang) {
        List<Cookie> cookies = client.getCookieStore().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equalsIgnoreCase(connConfig.get("DEFAULT_COOKIE_LANG_NAME"))) {
                BasicClientCookie coo = new BasicClientCookie("", "");
                coo.setDomain(cookie.getDomain());
                coo.setExpiryDate(cookie.getExpiryDate());
                coo.setPath(cookie.getPath());
                coo.setSecure(cookie.isSecure());
                coo.setValue(Integer.toString(lang));
                coo.setVersion(cookie.getVersion());
                cookies.remove(cookie);
                cookies.add(coo);
            }
        }
    }

    public void fixLang() {
        fixLang(0);
    }

    public int Login(String email, String pass) {
        if (this.getLoginStatus() == LOGINSTATUS_LOGGED) {
            return LOGIN_ALREADY_LOGGED;
        }
        if (email != null && pass != null) {
            HashMap<String, String> map = new HashMap<String, String>();
            map.put(connConfig.get("DEFAULT_EMAIL_STRING"), email);
            map.put(connConfig.get("DEFAULT_PASS_STRING"), pass);
            Post(connConfig.get("DEFAULT_LOGIN_PAGE"), map);
            List<Cookie> cookies = client.getCookieStore().getCookies();
            for (Cookie cookie : cookies) {
                //System.out.println(cookie.toString());
                if (cookie.getName().equalsIgnoreCase(connConfig.get("DEFAULT_COOKIE_USERID_NAME"))) {
                    this.setUserID(cookie.getValue());
                    this.setLoginStatus(LOGINSTATUS_LOGGED);
                }
            }
            if (this.getLoginStatus() == LOGINSTATUS_LOGGED) {
                this.setEmail(email);
                this.setPass(pass);
                return LOGIN_OK;
            } else {
                return LOGIN_ERROR;
            }
        } else {
            return LOGIN_BAD_ARGUMENT;
        }
    }

    /**
     * Get запрос к серверу с использованием текущих параметров подключения
     * @param request Запрос, может быть локальным - login.php?login="login"
     * или полным - http://vkontakte.ru/login.php?login="login"
     * @return строку с контентом
     */
    public String Get(String request) {
        if (!request.startsWith("http://")) {
            request = this.getServerAddress() + request;
        }
        HttpGet get = new HttpGet(request);
        HttpResponse resp = null;
        try {
            resp = client.execute(get);
        } catch (IOException ex) {
            Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
        }
        if (resp != null) {
            HttpEntity entity = resp.getEntity();
            String content = null;
            try {
                InputStream stream = entity.getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
                String str = reader.readLine();
                while (str != null) {
                    content += str + "\n";
                    str = reader.readLine();
                }
            } catch (IOException ex) {
                Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalStateException ex) {
                Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
            }
            return content;
        } else {
            return null;
        }
    }

    /**
     * Post запрос к серверу с использованием текущих параметров подключения
     * @param request Запрос, может быть локальным - login.php?login="login"
     * или полным - http://vkontakte.ru/login.php?login="login"
     * @param params HashMap c парами имя_переменной-значение
     * @return строку с контентом
     */
    public String Post(String request, HashMap<String, String> params) {
        if (!request.startsWith("http://")) {
            request = this.getServerAddress() + request;
        }
        HttpPost post = new HttpPost(request);
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        for (String key : params.keySet()) {
            nvps.add(new BasicNameValuePair(key, params.get(key)));
        }
        try {
            post.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
        } catch (UnsupportedEncodingException ex) {
            Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
        }
        HttpResponse resp = null;
        try {
            resp = client.execute(post);
        } catch (IOException ex) {
            Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
        }
        if (resp != null) {
            HttpEntity entity = resp.getEntity();
            String content = null;
            try {
                InputStream stream = entity.getContent();
                BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
                String str = reader.readLine();
                while (str != null) {
                    content += str + "\n";
                    str = reader.readLine();
                }
            } catch (IOException ex) {
                Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalStateException ex) {
                Logger.getLogger(Connection.class.getName()).log(Level.SEVERE, null, ex);
            }
            return content;
        } else {
            return null;
        }
    }

    /**
     * Возвращает текущий e-mail пользователя
     * @return текущий e-mail пользователя
     */
    public String getEmail() {
        return email;
    }

    protected void setEmail(String email) {
        this.email = email;
    }

    /**
     * Возвращает текущий пароль пользователя
     * @return текущий пароль пользователя
     */
    public String getPass() {
        return pass;
    }

    protected void setPass(String pass) {
        this.pass = pass;
    }

}
